import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

//继承JFrame  为了直接复用Swing框架中窗口管理的能力
//为了子类可以直接调用JFrame public 方法

//ActionListener 是java中事件处理机制的核心部分
//为了建立计算机组件和用户操作间的响应机制
public class All  extends JFrame implements ActionListener{
    //声明界面组件
    //上下两个容器面板 文本框区域 按键区域
    private JPanel north,center,south;
    //文本框 显示计算过程 
    private JTextField field;
    //按键
    private JButton[] btns;
    //音乐控制按钮
    private JButton playBtn, pauseBtn, stopBtn;
    private Clip backgroundMusic;

   

     //初始化窗口 构造方法 无参
     public All(){
        setTitle("计算器");
        setSize(700,700);
        //设置窗口关闭时程序
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        //设置窗口居中显示
        setLocationRelativeTo(null);

        //初始化界面组件
        initComponent();

        //加载背景音乐
        loadBackgroundMusic();

        //设置窗口显示
        setVisible(true);

    }
 

     //初始化界面组件
    private void initComponent(){

        //System.out.println("hello,calculator");
        //容器面板 文本框区域
        north = new JPanel();
        //按钮区域
        center = new JPanel();
        //音乐控制区域
        south = new JPanel();

        //文本框
        field = new JTextField();
        //设置输入框大小 首选尺寸
        field.setPreferredSize(new Dimension(700,200));
        //禁止文字输入
        field.setEditable(false);
        //设置输入框文字大小
        field.setFont(new Font("SansSerif",Font.BOLD,26));

        //设置背景色
        field.setBackground(Color.PINK);
        field.setForeground(Color.BLUE);

        //JButton[] btns  按钮内容
        String[] str=new String[]{
            "7","8","9","+",
            "4","5","6","-",
            "1","2","3","×",
            "0",".","=","÷",
            "C","B","T","S",
        };
        //按钮数组
        btns = new JButton[str.length];

        for(int i=0; i<btns.length ; i++){
            btns[i] = new JButton(str[i]);
            btns[i].setFont(new Font("SansSerif",Font.BOLD,25));

             // 设置按钮颜色
            if (str[i].matches("[0-9.]")) {
                btns[i].setBackground(new Color(220, 220, 220));
            } else if (str[i].matches("[+\\-×÷=]")) {
                btns[i].setBackground(new Color(255, 165, 0));
                btns[i].setForeground(Color.WHITE);
            } else {
                btns[i].setBackground(new Color(100, 149, 237));
                btns[i].setForeground(Color.WHITE);
            }
            btns[i].setBorder(BorderFactory.createRaisedSoftBevelBorder());
            btns[i].setFocusPainted(false);
        }
        
      
        //顶部面板使用边界布局
        north.setLayout(new BorderLayout());
       


        //中间面板使用5行4列网格布局
        center.setLayout(new GridLayout(5,4));
        //组件设置
        //按钮添加到center面板
        for (JButton btn : btns){
            center.add(btn);//遍历将按钮添加到center面板
        }
        

        //音乐控制区域
        playBtn = new JButton("播放");
        pauseBtn = new JButton("暂停");
        stopBtn = new JButton("停止");
    

        south.add(playBtn);
        south.add(pauseBtn);
        south.add(stopBtn);

        //文本框添加到顶部面板，居中
        north.add(field,BorderLayout.CENTER);
        //将顶部面板添加到窗口中
        add(north,BorderLayout.NORTH);
        add(center,BorderLayout.CENTER);
        add(south,BorderLayout.SOUTH);

        //绑定按钮的监听事件
        for (JButton btn : btns){
            btn.addActionListener(this);//this 当前对象实例
        }

         // 绑定音乐控制按钮事件
         playBtn.addActionListener(this);
         pauseBtn.addActionListener(this);
         stopBtn.addActionListener(this);
    }


    // 加载背景音乐
    private void loadBackgroundMusic() {
        try {
            // 注意：需要替换为实际的音频文件路径
            File audioFile = new File("爱情讯息.wav");
            if (!audioFile.exists()) {
                System.out.println("背景音乐文件不存在，请检查路径: " + audioFile.getAbsolutePath());
                return;
            }

            AudioInputStream audioStream = AudioSystem.getAudioInputStream(audioFile);
            AudioFormat format = audioStream.getFormat();
            DataLine.Info info = new DataLine.Info(Clip.class, format);

            backgroundMusic = (Clip) AudioSystem.getLine(info);
            backgroundMusic.open(audioStream);

            // 设置为循环播放
            backgroundMusic.loop(Clip.LOOP_CONTINUOUSLY);

        } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
            System.out.println("加载背景音乐时出错: " + e.getMessage());
            e.printStackTrace();
        }
    }


    private void setBtnText(String text){
        switch(text){
          case "C"://清空
            field.setText("");
            break;

          case "B": //退格
            //1.获取输入框内容
            String numText = field.getText();
            //isEmpty()
            if(numText.length()!=0){
              //字符串长度减一
              String lastText = numText.substring(0, numText.length()-1);
              //System.out.println("lastText: "+lastText);
              field.setText(lastText);
            }else{
            }
            break;

          case "T": //时间
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            field.setText(sdf.format(new Date()));
            break;

          case "S": //科学计数法
            try {
                    double num = Double.parseDouble(field.getText());
                    field.setText(String.format("%.4e", num));
                } catch (NumberFormatException e) {
                    field.setText("Error: 请输入有效数字");
                }
            break;


          case "=":
            //field.getText();
            calculate();
            break;
            
          default:  
          //文字放到输入框
            String oldText = field.getText();
            handleInput(text, oldText);
            break;
        }
        
    }

     // 处理输入逻辑
     private void handleInput(String text, String oldText) {
        // 如果当前是错误信息，清空后再输入
        if (oldText.startsWith("Error:")) {
            oldText = "";
        }
        
        // 处理运算符输入
        if (text.matches("[+\\-×÷.]")) {
            // 如果当前为空且输入的是运算符(除了减号)，不处理
            if (oldText.isEmpty() && !text.equals("-")) {
                if (text.equals(".")) {
                    field.setText("0.");
                }
                return;
            }
            
            // 如果最后一个字符已经是运算符或小数点
            if (!oldText.isEmpty() && oldText.substring(oldText.length() - 1).matches("[+\\-×÷.]")) {
                // 如果新输入的是小数点且最后一个字符不是小数点
                if (text.equals(".") && !oldText.substring(oldText.length() - 1).equals(".")) {
                    //如果最后一个字符是运算符，则自动补0
                    if (oldText.substring(oldText.length() - 1).matches("[+\\-×÷]")) {
                        field.setText(oldText + "0.");
                    } else {
                    field.setText(oldText + text);
                }
                }
                return;
            }
        }
        
        // 处理小数点特殊情况
        if (text.equals(".")) {
            // 如果当前为空，自动补0
            if (oldText.isEmpty()) {
                field.setText("0.");
                return;
            }
            
            // 检查当前数字是否已经包含小数点
            String[] parts = oldText.split("[+\\-×÷]");
            if (parts.length > 0 && parts[parts.length - 1].contains(".")) {
                return;
            }
        }
        
        field.setText(oldText + text);
    }


    //执行计算
    private void calculate(){

      //有× ÷ 要替换* /
      String expression = field.getText();

      // 替换数学符号为JavaScript可识别的符号
      expression = expression.replaceAll("×", "*").replaceAll("÷", "/");
    
      //使用js计算引擎
      ScriptEngineManager manager = new ScriptEngineManager();
      //初始化计算引擎 使用javascript解析数学表达式
      ScriptEngine engine = manager.getEngineByName("javascript");
     try{
       //计算  可能出现异常
       Object result = engine.eval(expression);
       field.setText(result.toString());
    }catch(ScriptException e){
      //catch 中放的是异常的处理方式
      field.setText("Error: 请正确计算！");
    }
    }


    //实现接口抽象方法 处理事件
    @Override
    public void actionPerformed(ActionEvent a){
        //捕获 ActionListener监听事件
        //System.out.println(a.getSource());
        //获取被点击的按钮
        Object source = a.getSource();
        if(source instanceof JButton){
            JButton btn = (JButton)source;
            String text = btn.getText();

             // 处理音乐控制
             if ("播放".equals(text)) {
                if (backgroundMusic != null) {
                    if (!backgroundMusic.isRunning()) {
                        backgroundMusic.start();
                    }
                } else {
                    loadBackgroundMusic();
                }
                return;
            } else if ("暂停".equals(text)) {
                if (backgroundMusic != null && backgroundMusic.isRunning()) {
                    backgroundMusic.stop();
                }
                return;
            } else if ("停止".equals(text)) {
                if (backgroundMusic != null) {
                    backgroundMusic.stop();
                    backgroundMusic.setFramePosition(0); // 重置到开始位置
                }
                return;
            }
            

            //处理对应按键文字
            setBtnText(text);
        }

    }
    public static void main(String[] args) {
        //System.out.println("hello,calculator");
        //创建类对象 -线程不安全
        //new Calculator();
        //是java Swing 开发中确保线程安全的核心代码
        SwingUtilities.invokeLater(All::new);
    }
}

